{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "3aa6ec79",
   "metadata": {},
   "outputs": [],
   "source": [
    "import mindspore\n",
    "import mindspore.nn as nn\n",
    "import mindspore.ops as ops\n",
    "from d2l import mindspore as d2l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b1361cba",
   "metadata": {},
   "outputs": [],
   "source": [
    "def trans_conv(X, K):\n",
    "    h, w = K.shape\n",
    "    Y = ops.zeros((X.shape[0] + h - 1, X.shape[1] + w - 1))\n",
    "    for i in range(X.shape[0]):\n",
    "        for j in range(X.shape[1]):\n",
    "            Y[i: i + h, j: j + w] += X[i, j] * K\n",
    "    return Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6059fc3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[3, 3], dtype=Float32, value=\n",
       "[[ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00],\n",
       " [ 0.00000000e+00,  4.00000000e+00,  6.00000000e+00],\n",
       " [ 4.00000000e+00,  1.20000000e+01,  9.00000000e+00]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = mindspore.Tensor([[0.0, 1.0], [2.0, 3.0]])\n",
    "K = mindspore.Tensor([[0.0, 1.0], [2.0, 3.0]])\n",
    "trans_conv(X, K)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e59b8fa4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[1, 1, 3, 3], dtype=Float32, value=\n",
       "[[[[ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00],\n",
       "   [ 0.00000000e+00,  4.00000000e+00,  6.00000000e+00],\n",
       "   [ 4.00000000e+00,  1.20000000e+01,  9.00000000e+00]]]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, K = X.reshape(1, 1, 2, 2), K.reshape(1, 1, 2, 2)\n",
    "tconv = nn.Conv2dTranspose(1, 1, kernel_size=2, pad_mod='valid', has_bias=False, weight_init=K)\n",
    "tconv(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5f87c940",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[1, 1, 1, 1], dtype=Float32, value=\n",
       "[[[[ 4.00000000e+00]]]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tconv = nn.Conv2dTranspose(1, 1, kernel_size=2, pad_mode='pad', \n",
    "                           padding=1, has_bias=False, weight_init=K)\n",
    "tconv(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b358a901",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[1, 1, 4, 4], dtype=Float32, value=\n",
       "[[[[ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  1.00000000e+00],\n",
       "   [ 0.00000000e+00,  0.00000000e+00,  2.00000000e+00,  3.00000000e+00],\n",
       "   [ 0.00000000e+00,  2.00000000e+00,  0.00000000e+00,  3.00000000e+00],\n",
       "   [ 4.00000000e+00,  6.00000000e+00,  6.00000000e+00,  9.00000000e+00]]]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tconv = nn.Conv2dTranspose(1, 1, kernel_size=2, stride=2, pad_mode='valid', has_bias=False, weight_init=K)\n",
    "tconv(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "5bbb56ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import mindspore.common.initializer as init\n",
    "\n",
    "X = ops.randn((1, 10, 16, 16))\n",
    "conv = nn.Conv2d(10, 20, kernel_size=5, pad_mode='pad', padding=2, stride=3, has_bias=True)\n",
    "k = (conv.group / (conv.in_channels * conv.kernel_size[0] * conv.kernel_size[1])) ** 0.5\n",
    "conv.weight_init = init.initializer(init.Uniform(k), conv.weight.shape, conv.weight.dtype)\n",
    "conv.bias_init = init.initializer(init.Uniform(k), conv.bias.shape, conv.bias.dtype)\n",
    "\n",
    "tconv = nn.Conv2dTranspose(20, 10, kernel_size=5, pad_mode='pad', padding=2, stride=3)\n",
    "conv.weight_init = init.initializer(init.Uniform(k), conv.weight.shape, conv.weight.dtype)\n",
    "conv.bias_init = init.initializer(init.Uniform(k), conv.bias.shape, conv.bias.dtype)\n",
    "tconv(conv(X)).shape == X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "afeeb44d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[2, 2], dtype=Float32, value=\n",
       "[[ 2.70000000e+01,  3.70000000e+01],\n",
       " [ 5.70000000e+01,  6.70000000e+01]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = ops.arange(9.0).reshape(3, 3)\n",
    "K = mindspore.Tensor([[1.0, 2.0], [3.0, 4.0]])\n",
    "Y = d2l.corr2d(X, K)\n",
    "Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f0dabb00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[4, 9], dtype=Float32, value=\n",
       "[[ 1.00000000e+00,  2.00000000e+00,  0.00000000e+00 ...  0.00000000e+00,  0.00000000e+00,  0.00000000e+00],\n",
       " [ 0.00000000e+00,  1.00000000e+00,  2.00000000e+00 ...  0.00000000e+00,  0.00000000e+00,  0.00000000e+00],\n",
       " [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00 ...  3.00000000e+00,  4.00000000e+00,  0.00000000e+00],\n",
       " [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00 ...  0.00000000e+00,  3.00000000e+00,  4.00000000e+00]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def kernel2matrix(K):\n",
    "    k, W = ops.zeros(5), ops.zeros((4, 9))\n",
    "    k[:2], k[3:5] = K[0, :], K[1, :]\n",
    "    W[0, :5], W[1, 1:6], W[2, 3:8], W[3, 4:] = k, k, k, k\n",
    "    return W\n",
    "\n",
    "W = kernel2matrix(K)\n",
    "W"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "fab9c18a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[2, 2], dtype=Bool, value=\n",
       "[[ True,  True],\n",
       " [ True,  True]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y == ops.matmul(W, X.reshape(-1)).reshape(2, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "33584d70",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[3, 3], dtype=Bool, value=\n",
       "[[ True,  True,  True],\n",
       " [ True,  True,  True],\n",
       " [ True,  True,  True]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Z = trans_conv(Y, K)\n",
    "Z == ops.matmul(W.T, Y.reshape(-1)).reshape(3, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92ea627d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
